package com.xxx.ware.ware_manage_sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxx.ware.ware_manage_sys.bean.constant.BaseConstant;
import com.xxx.ware.ware_manage_sys.bean.dto.LoginTicket;
import com.xxx.ware.ware_manage_sys.bean.dto.UserQueryDto;
import com.xxx.ware.ware_manage_sys.bean.dto.UserSaveUpdateDto;
import com.xxx.ware.ware_manage_sys.bean.dto.WebResultDto;
import com.xxx.ware.ware_manage_sys.bean.entity.user.WmsUser;
import com.xxx.ware.ware_manage_sys.bean.enums.RoleEnum;
import com.xxx.ware.ware_manage_sys.bean.enums.SexEnum;
import com.xxx.ware.ware_manage_sys.bean.vo.UserVo;
import com.xxx.ware.ware_manage_sys.mapper.WmsUserMapper;
import com.xxx.ware.ware_manage_sys.service.IUserService;
import com.xxx.ware.ware_manage_sys.utils.CommonUtil;
import com.xxx.ware.ware_manage_sys.utils.RedisClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<WmsUserMapper, WmsUser> implements IUserService, BaseConstant {

    @Autowired
    private RedisClient redisClient;

    @Override
    public Boolean saveUser(UserSaveUpdateDto userSaveUpdateDto) throws Exception {
        //添加之前，判断当前用户是否已经存在
        String userAccount = userSaveUpdateDto.getUserAccount();
        String userName = userSaveUpdateDto.getUserName();
        String userPhone = userSaveUpdateDto.getUserPhone();
        String userSex = userSaveUpdateDto.getUserSex();
        String userRole = userSaveUpdateDto.getUserRole();
        WmsUser soleWmsUser = getUserBySoleKey(userAccount, userName, userPhone);
        if (soleWmsUser != null) {
            throw new Exception("此用户已存在，用户账号：" + userAccount +
                                           "，用户姓名：" + userName +
                                           "，用户联系方式：" + userPhone);
        }
        WmsUser wmsUser = new WmsUser();
        BeanUtils.copyProperties(userSaveUpdateDto, wmsUser);
        wmsUser.setUserSex(Integer.parseInt(StringUtils.isBlank(userSex) ? "0" : userSex));
        wmsUser.setUserRole(Integer.parseInt(StringUtils.isBlank(userRole) ? "0" : userRole));
        return save(wmsUser);
    }

    @Override
    public WmsUser getUserBySoleKey(String userAccount, String userName, String userPhone){
        LambdaQueryWrapper<WmsUser> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(WmsUser::getUserAccount, userAccount);
        queryWrapper.eq(WmsUser::getUserName, userName);
        queryWrapper.eq(WmsUser::getUserPhone, userPhone);
        queryWrapper.eq(WmsUser::getStatus, 1);
        queryWrapper.last("LIMIT 1");
        return this.getBaseMapper().selectOne(queryWrapper);
    }

    @Override
    public WebResultDto<UserVo> getUserList(UserQueryDto userQueryDto) throws Exception {
        Integer pageNo = userQueryDto.getPageNo();
        Integer pageSize = userQueryDto.getPageSize();
        String userAccount = userQueryDto.getUserAccount();
        String userName = userQueryDto.getUserName();
        String userPhone = userQueryDto.getUserPhone();

        LambdaQueryWrapper<WmsUser> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(StringUtils.isNotBlank(userAccount), WmsUser::getUserAccount, userAccount);
        queryWrapper.eq(StringUtils.isNotBlank(userName), WmsUser::getUserName, userName);
        queryWrapper.eq(StringUtils.isNotBlank(userPhone), WmsUser::getUserPhone, userPhone);
        queryWrapper.eq(WmsUser::getStatus, 1);
        queryWrapper.orderByDesc(WmsUser::getCreateTime);

        IPage<WmsUser> page = new Page<>(pageNo, pageSize);
        IPage<WmsUser> resultPage = this.getBaseMapper().selectPage(page, queryWrapper);
        if (resultPage == null || resultPage.getRecords() == null || resultPage.getRecords().isEmpty()) {
            return WebResultDto.getDataList(pageNo, pageSize, 0L, null);
        }
        List<UserVo> userVoList = resultPage.getRecords().stream().map(
                e -> {
                    UserVo userVo = new UserVo();
                    BeanUtils.copyProperties(e, userVo);
                    userVo.setUserSex(SexEnum.getSex(String.valueOf(e.getUserSex())));
                    userVo.setUserRole(RoleEnum.getAdminRole(String.valueOf(e.getUserRole())));
                    userVo.setStatus(e.getStatus().equals(1) ? "生效" : "失效");
                    return userVo;
                }
        ).collect(Collectors.toList());
        return WebResultDto.getDataList(pageNo, pageSize, resultPage.getTotal(), userVoList);
    }

    @Override
    public Boolean updateUser(UserSaveUpdateDto userSaveUpdateDto) throws Exception {
        //修改后的数据不能和已存在的数据重复
        String userAccount = userSaveUpdateDto.getUserAccount();
        String userName = userSaveUpdateDto.getUserName();
        String userPhone = userSaveUpdateDto.getUserPhone();
        WmsUser soleWmsUser = getUserBySoleKey(userAccount, userName, userPhone);
        //判断条件：账号+姓名+联系方式查询存在，同时id不相同，说明即将修改的数据和数据库的数据重复
        if (soleWmsUser != null && !soleWmsUser.getId().equals(userSaveUpdateDto.getId())) {
            throw new Exception("此用户已存在，用户账号：" + userAccount +
                    "，用户姓名：" + userName +
                    "，用户联系方式：" + userPhone);
        }

        //先删除缓存，再更新数据库
        String userKey = "User:" + userSaveUpdateDto.getId();
        if(!redisClient.delDataByKey(userKey)){
            log.warn("删除缓存失败，Key：{}", userKey);
        }

        LambdaUpdateWrapper<WmsUser> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(WmsUser::getId, userSaveUpdateDto.getId());
        updateWrapper.set(WmsUser::getUserAccount, userSaveUpdateDto.getUserAccount());
        updateWrapper.set(WmsUser::getUserName, userSaveUpdateDto.getUserName());
        updateWrapper.set(WmsUser::getUserAge, userSaveUpdateDto.getUserAge());
        updateWrapper.set(WmsUser::getUserSex, userSaveUpdateDto.getUserSex());
        updateWrapper.set(WmsUser::getUserRole, userSaveUpdateDto.getUserRole());
        updateWrapper.set(WmsUser::getUserPhone, userSaveUpdateDto.getUserPhone());
        return update(updateWrapper);
    }

    @Override
    public Boolean removeUser(Long id) throws Exception {
        //先删缓存，再删数据库
        String userKey = "User:" + id;
        if(!redisClient.delDataByKey(userKey)){
            throw new Exception("删除缓存失败，缓存Key：" + userKey);
        }
        WmsUser wmsUser = new WmsUser();
        wmsUser.setId(id);
        wmsUser.setStatus(2);
        return updateById(wmsUser);
    }

    @Override
    public UserVo getUserByNamePwd(String userName, String userPwd) throws Exception {
        WmsUser loginUser = getLoginUser(userName, userPwd);
        if (loginUser == null) {
            throw new Exception("当前用户不存在，用户名：" + userName + "，密码：" + userPwd);
        }
        //更新登录凭证
        LambdaUpdateWrapper<WmsUser> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(WmsUser::getId, loginUser.getId());
        loginUser.setUserTicket(CommonUtil.generateUUID() + "-" + loginUser.getId());
        update(loginUser, updateWrapper);
        //添加登录凭证后回显
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(loginUser, userVo);
        return userVo;
    }

    private WmsUser getLoginUser(String userName, String userPwd){
        LambdaQueryWrapper<WmsUser> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(WmsUser::getUserName, userName);
        queryWrapper.eq(WmsUser::getUserPwd, userPwd);
        queryWrapper.eq(WmsUser::getStatus, 1);
        queryWrapper.last("LIMIT 1");
        return this.getBaseMapper().selectOne(queryWrapper);
    }

    @Override
    public UserVo getUserDetail(Long id) {
        //从缓存中获取
        String key = "User:" + id;
        UserVo cacheUser = (UserVo)redisClient.getData(key);
        if (cacheUser != null) {
            log.info("缓存中获取用户，{}", cacheUser);
            return cacheUser;
        }
        //缓存没有，查数据库
        LambdaQueryWrapper<WmsUser> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(WmsUser::getId, id);
        WmsUser wmsUser = this.getBaseMapper().selectOne(queryWrapper);
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(wmsUser, userVo);
        //枚举转换
        userVo.setUserSex(SexEnum.getSex(String.valueOf(wmsUser.getUserSex())));
        userVo.setUserRole(RoleEnum.getAdminRole(String.valueOf(wmsUser.getUserRole())));
        //同步到缓存中
        redisClient.setData(key, userVo);
        return userVo;
    }
}
